package io.jsen.meta.diff.feature;

import io.jsen.meta.diff.field.MetaFieldDefine;
import io.jsen.meta.diff.obj.Convert;

import java.util.function.Supplier;

/**
 * 控制字段行为
 * <p>
 * 1，定义字段传入特殊值作为删除
 * 2，定义diff索引构建方式
 *
 * @author jsen
 * @date 2021/09/18
 **/
public interface FieldControl {

    /**
     * 对某个字段定义，这个值是否为删除值，用于转换为meta的时候的diff，把某个字段变为MetaDelete
     * <p>
     * 比如年龄字段，我想定义-1表示删除这个字段
     *
     * @param metaFieldDefine 字段定义
     * @param val             字段值
     * @return 是否是删除字段
     */
    <T> boolean isDelVal(MetaFieldDefine metaFieldDefine, T val);

    /**
     * 获取字段定义对应的删除值，如果isDelVal定义了某个特殊值为某个字段的删除值，
     * 理论上这里必须返回这个字段对应的这个删除值
     *
     * @param metaFieldDefine 字段定义
     * @return 删除字段
     */
    <T> T getDelVal(MetaFieldDefine metaFieldDefine);

    /**
     * 自定义索引构建
     *
     * @param metaFieldDefine     字段
     * @param val                 当前字段对应的值
     * @param defaultIndexCreator 默认的构建索引方法（兜底）
     * @param <T>                 字段值的类型
     * @return 索引
     */

    default <T> String buildIndex(MetaFieldDefine metaFieldDefine, T val, Supplier<String> defaultIndexCreator) {
        return defaultIndexCreator.get();
    }

    /**
     * 转为meta的转换器
     *
     * @param metaFieldDefine 字段
     * @return convert
     */
    default <S, T> Convert<S, T> metaConvert(MetaFieldDefine metaFieldDefine) {
        return null;
    }

    /**
     * 转为native的转换器
     *
     * @param metaFieldDefine 字段
     * @return convert
     */
    default <S, T> Convert<S, T> nativeConvert(MetaFieldDefine metaFieldDefine) {
        return null;
    }
}
